﻿#include<iostream>
#include<functional>
using namespace std;


//template<class T>
//class unique_ptr
//{
//public:
//	// 显式构造函数，接受一个指向 T 类型对象的指针 ptr
//	// 显式关键字 explicit 防止隐式类型转换
//	// 将传入的指针赋值给类的私有成员 _ptr
//	explicit unique_ptr(T* ptr)
//		:_ptr(ptr)
//	{
//	}
//	//判断_ptr 是否为空，如果不为空，则输出要删除的指针地址，并使用 delete 释放该指针指向的内存
//	~unique_ptr()
//	{
//		if (_ptr)
//		{
//			cout << "delete:" << _ptr << endl;
//			delete _ptr;
//		}
//	}
//	// 像指针⼀样使⽤ 
//	T& operator*()
//	{
//		return *_ptr;
//	}
//	T* operator->()
//	{
//		return _ptr;
//	}
//	//把拷贝构造和赋值函数禁⽌掉
//	unique_ptr(const unique_ptr<T>&sp) = delete;
//	unique_ptr<T>& operator=(const unique_ptr<T>&sp) = delete;
//
//	// 移动构造函数，接受一个右值引用 sp
//	// 将 sp 的 _ptr 赋值给当前对象的 _ptr，并将 sp 的 _ptr 置为 nullptr
//	// 这样就将对象的所有权从 sp 转移到了当前对象
//	unique_ptr(unique_ptr<T> && sp)
//		:_ptr(sp._ptr)
//	{
//		sp._ptr = nullptr;
//	}
//	// 移动赋值运算符，接受一个右值引用 sp
//	// 首先释放当前对象 _ptr 指向的内存
//	// 然后将 sp 的 _ptr 赋值给当前对象的 _ptr，并将 sp 的 _ptr 置为 nullptr
//	// 实现对象所有权的转移
//	unique_ptr<T>& operator=(unique_ptr<T> && sp)
//	{
//		delete _ptr;
//		_ptr = sp._ptr;
//		sp._ptr = nullptr;
//	}
//private:
//	T* _ptr;
//};
struct Date
{
	int _year;
	int _month;
	int _day;
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{
	}
	~Date()
	{
		cout << "~Date()" << endl;
	}
};


namespace bit
{
	template<class T>
	class shared_ptr
	{
	public:
		//explicit防止隐式类型转换
		explicit shared_ptr(T* ptr = nullptr)
			: _ptr(ptr)
			, _pcount(new int(1))//构造引用计数，为1
		{
		}
		// 带自定义删除器的构造函数模板
		// 接受一个指向 T 类型对象的指针 ptr 和一个可调用对象 del 作为自定义删除器
		// 初始化成员变量 _ptr 为传入的指针，_pcount 引用计数初始化为 1，_del 为传入的自定义删除器
		template<class D>
		shared_ptr(T* ptr, D del)
			: _ptr(ptr)
			, _pcount(new int(1))
			, _del(del)
		{
		}
		//拷贝构造函数，接受一个 shared_ptr<T> 类型的常量引用 sp
		shared_ptr(const shared_ptr<T>& sp)
			:_ptr(sp._ptr)
			, _pcount(sp._pcount)
			, _del(sp._del)
		{
			++(*_pcount);
		}

		//release() 函数释放资源
		void release()
		{
			//当引用计数减 1 后变为 0 时,说明当前 shared_ptr 是最后一个管理该对象的实例
			if (--(*_pcount) == 0)
			{
				// 最后⼀个管理的对象，释放资源
				_del(_ptr);
				delete _pcount;
				_ptr = nullptr;
				_pcount = nullptr;
			}
		}

		// 赋值运算符重载，接受一个 shared_ptr<T> 类型的常量引用 sp
		// 如果当前对象的 _ptr 不等于 sp 的 _ptr，说明不是同一个对象
		// 先调用 release() 释放当前对象管理的资源
		// 然后将 sp 的成员变量 _ptr、_pcount 和 _del 赋值给当前对象
		// 最后将引用计数 _pcount 加 1
		
		// 假设 sp1 = sp3
		shared_ptr<T>& operator=(const shared_ptr<T>& sp)
		{
			if (_ptr != sp._ptr)
			{
				//调用 release() 函数释放资源
				release();//释放sp1管理的资源
				//将 sp3 的成员变量赋值给sp1,
				_ptr = sp._ptr;
				_pcount = sp._pcount;
				++(*_pcount);//引用计数加1
				_del = sp._del;
			}
			return *this;
		}

		~shared_ptr()
		{
			//调用 release() 函数释放资源
			release();
		}
		// 获取管理的对象指针的成员函数
		// 返回 _ptr 的值
		T* get() const
		{
			return _ptr;
		}
		//获取当前对象的引用计数的成员函数
		//返回 _pcount 指向的值
		int use_count() const
		{
			return *_pcount;
		}
		T& operator*()
		{
			return *_ptr;
		}
		T* operator->()
		{
			return _ptr;
		}
	private:
		T* _ptr;
		int* _pcount;
		//atomic<int>* _pcount;
		
		//_del接收的是一个可调用对象，用来释放资源，没有可调用对象，使用lambda的缺省值
		function<void(T*)> _del = [](T* ptr) {delete ptr; };
	};
}


int main()
{
	bit::shared_ptr<Date> sp1(new Date);
	// ⽀持拷⻉ 
	bit::shared_ptr<Date> sp2(sp1);
	bit::shared_ptr<Date> sp3(new Date(1014,3,3));

	//自己给自己赋值
	sp3 = sp3;
	sp1 = sp2;

	sp1 = sp3;
	sp2 = sp3;

	return 0;
}
